package com.itheima.service;

import com.alibaba.dubbo.config.annotation.Service;
import com.itheima.dao.MemberDao;
import com.itheima.dao.OrderDao;
import com.itheima.dao.OrderSettingDao;
import com.itheima.dao.SetmealDao;
import com.itheima.pojo.CheckGroup;
import com.itheima.pojo.CheckItem;
import com.itheima.pojo.Member;
import com.itheima.pojo.Setmeal;
import com.itheima.utils.DateUtils;
import org.apache.commons.lang3.text.StrBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * 数据统计服务
 */

@Service(interfaceClass = ReportService.class)
@Transactional
public class ReportServiceImpl implements ReportService {
    @Autowired
    private MemberDao memberDao;
    @Autowired
    private OrderDao orderDao;
    @Autowired
    private OrderSettingDao orderSettingDao;
    @Autowired
    private SetmealDao setmealDao;

    //查询运用数据

    /**
     * reportDate:null,
     * todayNewMember :0,
     * totalMember :0,
     * thisWeekNewMember :0,
     * thisMonthNewMember :0,
     * todayOrderNumber :0,
     * todayVisitsNumber :0,
     * thisWeekOrderNumber :0,
     * thisWeekVisitsNumber :0,
     * thisMonthOrderNumber :0,
     * thisMonthVisitsNumber :0,
     * hotSetmeal :[
     * {name:'阳光爸妈升级肿瘤12项筛查（男女单人）体检套餐',setmeal_count:200,proportion:0.222},
     * {name:'阳光爸妈升级肿瘤12项筛查体检套餐',setmeal_count:200,proportion:0.222}
     * ]
     */
    public Map<String, Object> getBusinessReportData() throws Exception {
        //获得当前系统时间
        String today = DateUtils.parseDate2String(DateUtils.getToday());
        //动态获得本周一的日期
        String thisWeekMonday = DateUtils.parseDate2String(DateUtils.getThisWeekMonday());
        //动态获得本月第一天的日期
        String firstDay4ThisMonth = DateUtils.parseDate2String(DateUtils.getFirstDay4ThisMonth());

        //今日新增会员数
        Integer todayNewMember = memberDao.findMemberCountByDate(today);//select count(id) from t_member where regTime = today

        //总会员数据
        Integer totalMember = memberDao.findMemberTotalCount();

        //本周新增会员数
        Integer thisWeekNewMember = memberDao.findMemberCountAfterDate(thisWeekMonday);

        //本月新增会员数
        Integer thisMonthNewMember = memberDao.findMemberCountAfterDate(firstDay4ThisMonth);

        //今日预约数
        Integer todayOrderNumber = orderDao.findOrderCountByDate(today);

        //今日到诊数
        Integer todayVisitsNumber = orderDao.findVisitsCountByDate(today);

        //本周预约数
        Integer thisWeekOrderNumber = orderDao.findOrderCountAfterDate(thisWeekMonday);

        //本周到诊数
        Integer thisWeekVisitsNumber = orderDao.findVisitsCountAfterDate(thisWeekMonday);

        //本月预约数
        Integer thisMonthOrderNumber = orderDao.findOrderCountAfterDate(firstDay4ThisMonth);

        //本月到诊数
        Integer thisMonthVisitsNumber = orderDao.findVisitsCountAfterDate(firstDay4ThisMonth);

        //热门套餐
        List<Map> hotSetmeal = orderDao.findHotSetmeal();

        Map<String, Object> result = new HashMap<>();
        result.put("reportDate", today);
        result.put("todayNewMember", todayNewMember);
        result.put("totalMember", totalMember);
        result.put("thisWeekNewMember", thisWeekNewMember);
        result.put("thisMonthNewMember", thisMonthNewMember);
        result.put("todayOrderNumber", todayOrderNumber);
        result.put("thisWeekOrderNumber", thisWeekOrderNumber);
        result.put("thisMonthOrderNumber", thisMonthOrderNumber);
        result.put("todayVisitsNumber", todayVisitsNumber);
        result.put("thisWeekVisitsNumber", thisWeekVisitsNumber);
        result.put("thisMonthVisitsNumber", thisMonthVisitsNumber);
        result.put("hotSetmeal", hotSetmeal);

        return result;
    }

    /**
     * 获取给定日期范围内每天预约、到诊数量统计
     *
     * @param startDate
     * @param endDate
     * @return
     */
    @Override
    public Map<String, Object> findOrderAndVisitedByDate(Date startDate, Date endDate) {

        Map map = new HashMap();
        //1. 根据日期查询每日预约人数
        List<Integer> orderCountList = null;
        orderCountList = orderSettingDao.findOrderCountByDate(startDate, endDate);
        map.put("orderCount", orderCountList);
        //2. 根据日期查询每日到诊人数
        List<Integer> visitedCountList = orderSettingDao.findVisitedCountByDate(startDate, endDate);
        map.put("visitedCount", visitedCountList);
        //3. 获取日期集合
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(startDate);
        int start = calendar.get(Calendar.DATE);
        Calendar calendar1 = Calendar.getInstance();
        calendar1.setTime(endDate);
        int end = calendar1.get(Calendar.DATE);
        List dateList = new ArrayList();
        for (int i = start; i <= end; i++) {
            try {
                String date = DateUtils.parseDate2String(calendar.getTime());
                dateList.add(date);
                calendar.add(Calendar.DATE, 1);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        map.put("dateList", dateList);
        return map;
    }

    /**
     * 获取给定日期范围各套餐体检收入及总收入
     *
     * @param startDate
     * @param endDate
     * @return
     */
    @Override
    public Map<String, Object> findMedicalIncomeByDate(Date startDate, Date endDate) {
        Map map = new HashMap();
        // 封装套餐名称的集合
        List<String> setmealNames = new ArrayList<>();
        List<Map<String, Object>> setmealIncomesList = setmealDao.getSetmealIncomeDetailsByDate(startDate, endDate);
        // 查询指定日期所有套餐总收入
        Long sumSetmealIncome = setmealDao.findSumSetmealIncomeByDate(startDate, endDate);
        if (setmealIncomesList != null && setmealIncomesList.size() > 0) {
            for (Map map1 : setmealIncomesList) {
                String name = (String) map1.get("name");//套餐名称
                setmealNames.add(name);
            }
        }
        setmealNames.add("总收入");
        HashMap sumMap = new HashMap();
        sumMap.put("value", sumSetmealIncome);
        sumMap.put("name", "总收入");
        setmealIncomesList.add(sumMap);
        map.put("setmealNames", setmealNames);
        map.put("setmealIncomesList", setmealIncomesList);
        return map;
    }

    /**
     * 获取会员年龄分布报表
     *
     * @return
     */
    @Override
    public Map<String, Object> findMemberAgeDistribute() {
        Map map = new HashMap();
        Map memberAgeAttrMap = memberDao.findMemberAgeDistribute();
        String phaseStr = (String) memberAgeAttrMap.get("phase");
        String numberStr = (String) memberAgeAttrMap.get("number");
        String[] phase = phaseStr.split(",");
        String[] memberNum = numberStr.split(",");
        map.put("phase", phase);
        map.put("memberNum", memberNum);
        return map;
    }


    public List<Map<String, Object>> getBusinessReportData1(Integer[] ids) throws Exception {
        //姓名
        //性别
        // 手机号

        List<Map<String, Object>> list = new ArrayList<>();


        for (Integer memberId : ids) {
            List<Integer> setmaelIds = orderDao.findSetmealIdByMemeberId(memberId);

            Map map = new HashMap();
            Member member = memberDao.findMember(memberId);
            map.put("name", member.getName());
            map.put("sex", member.getSex());
            map.put("phoneNumber", member.getPhoneNumber());

            // 如果会员没有预约过订单
            if (setmaelIds == null  || setmaelIds.size() == 0) {
                list.add(map);
                continue;
            }
            // 预约过订单
            for (Integer setmaelId : setmaelIds) {

                String address = orderDao.findAddress(setmaelId);  //地址
                map.put("address", address);
                Setmeal setmeal = setmealDao.findById4Detail(setmaelId);
                map.put("setmealName",setmeal.getName());          // 套餐名称
                List<CheckGroup> checkGroups = setmeal.getCheckGroups();

                StrBuilder checkGroupNames = new StrBuilder();     // 检查组名称
                StrBuilder checkItemNames = new StrBuilder();      // 检查项名称

                for (CheckGroup checkGroup : checkGroups) {
                    checkGroupNames.append(checkGroup.getName()).append(" ");
                    List<CheckItem> checkItems = checkGroup.getCheckItems();
                    for (CheckItem checkItem : checkItems) {
                        checkItemNames.append(checkItem.getName()).append(" ");
                    }
                }
                map.put("checkGroupNames",checkGroupNames.toString());
                map.put("checkItemNames",checkItemNames.toString());
                list.add(map);
            }

        }
        return list;
    }

}
